import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from "@/view/Home.vue"
import User from "@/view/User.vue"
import Main from "@/view/Main.vue"
import Mall from "@/view/Mall.vue"
import PageOne from '@/view/PageOne.vue'
import PageTwo from '@/view/PageTwo.vue'
import Login from '@/view/Login.vue'
import Cookie from "js-cookie"
import Error from "@/view/Error.vue"

Vue.use(VueRouter);

// 1.创建路由组件
// 2.将路由与组件进行映射
// 3.创建router实例


const routes = [
    // 主路由
    {
        path: '/', 
        component: Main,
        name: 'Main',
        redirect: '/home', // 重定向
        children: [
            // 子路由
            // { path: '/home',name: 'home', component: Home }, // 首页
            // { path: '/user',name: 'user', component: User }, // 用户管理
            // { path: '/mall',name: 'mall', component: Mall }, // 商铺管理
            // { path: '/page1',name: 'page1', component: PageOne }, // 页面1
            // { path: '/page2',name: 'page2', component: PageTwo }, // 页面2
        ]
    },
    {
        path: '/login',
        component: Login,
        name: 'login'
    },
    {
        path: '*',
        component: Error,
        name: 'Error'
    }
    
]

const router = new VueRouter({
    routes // (缩写) 相当于 routes: routes
})

// 添加全局前置导航守卫 
router.beforeEach((to, from, next) => {
    // 判断token是否存在
    const token = Cookie.get('token');
    // token不存在，说明当前用户未登录，应该跳转至登录页
    if(!token && to.name !== 'login') {
        next({name: 'login'});
    }else if(token && to.name === 'login') { // token存在，说明用户登录，此时跳转至首页
        next({name: 'home'})
    } else {
        next();
    }
})


export default router;

// 解决路由重复点击报错
// 缓存原来的 push 方法
const originalPush = VueRouter.prototype.push
//指定新的push方法
VueRouter.prototype.push = function (location, onResolve, onReject) {
  //制定了一个成功或者失败的回调
    if (onResolve || onReject) {
        //直接调用原来的 push 方法
        // originalPush(location, onResolve, onReject)  //这里使用 call 可以直接指定当前的 router 对象，要是没有这个就会默认是window 对象，启用严格模式之后就是 undefined
        return originalPush.call(this, location, onResolve, onReject)
    }
    //如果没有指明一个成功或者失败的回调，需要使用到catch处理
    return originalPush.call(this, location).catch((err) => {
        //如果是重复导航所引起的错误的话
        if (VueRouter.isNavigationFailure(err)) {
            //这个 return err 返回的是成功的 Promise，其中Promise的value是 err
            return err
        }
        //如果是其他的错误就会接着往下传
        return Promise.reject(err)
    })
}

//缓存原来的replace 方法
const originalReplace = VueRouter.prototype.replace
//指定了一个新的 replace 方法
VueRouter.prototype.replace = function (location, onResolve, onReject) {
    if (onResolve || onReject) {
        return originalReplace.call(this, location, onResolve, onReject)
    }
    return originalReplace.call(this, location).catch((err) => {
        if (VueRouter.isNavigationFailure(err)) {
            return err
        }
        return Promise.reject(err)
    })
}